home *** CD-ROM | disk | FTP | other *** search
-
- /* C O P Y R I G H T N O T I C E : */
- /* Copyright 1986 Eric Jul. May not be used for any */
- /* purpose without written permission from the author. */
-
-
- /*
- * $Header$
- * INTERFACE: Takes KMD parameters, see error msg.
- *
- * FUNCTION: Execute single KMD trace requests.
- *
- * IMPORTS: loads, see #include
- *
- * EXPORTS: Nothing.
- *
- * DESIGN: Send start trace message to the traced process and then
- * repeatedly receive and print data until stop trace
- * message arrives.
- *
- */
- #undef integer
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <stdio.h>
-
- #define mSUCCESS(X) (((X) & 7) == 1)
-
- typedef int KKStatus;
-
- #define MAXMESSAGESIZE 1000
- #include "Kernel/h/stdTypes.h"
- #include "Kernel/h/kmdDefs.h"
- #include "Kernel/h/emPorts.h"
- #include <netdb.h>
- #include <signal.h>
-
- #define endcase break
-
- int talkSock;
- struct sockaddr_in destSockDescr = {AF_INET};
- int prodTime = 1;
- int tracing = 0;
- char *tracename;
- int machineNameGiven = 0;
- char *machineName;
- int OK;
- static int pid = 0;
- static int pidGiven = 0;
- int MType, MInt;
- char MString[5000];
-
- /* Define signal handlers */
-
- void PipeHandler(sig)
- int sig;
- {
- printf("SIGPIPE>>> The connection to the process broke.\n");
- printf("Terminating\n");
- exit(sig);
- }
-
- void TerminationHandler(sig)
- int sig;
- {
- if (sig != 0) {
- printf("Terminating trace due to signal %d.\n", sig);
- }
- KMDSend(talkSock, KMDCLASTMSG, 0, "done");
- shutdown(talkSock, 1);
- while(mSUCCESS(KMDReceive(talkSock, &MType, &MInt, MString)));
- close(talkSock);
- exit(sig);
- };
-
-
- void Prodder()
- /* Prods the kernel by sending a SIGURG signal.
- Exponential backoff.
- */
- {
- /* kill(pid, SIGURG); */
- prodTime += prodTime;
- alarm(prodTime);
- }
-
- void SendTraceStart(fTraceName, fTraceLevel, fUseStdOut)
- char *fTraceName;
- int fTraceLevel;
- int fUseStdOut;
- {
- KKStatus kstat;
- if (fUseStdOut) {
- kstat = KMDSend(talkSock, KMDCTRACESTDOUT, fTraceLevel, fTraceName);
- } else {
- kstat = KMDSend(talkSock, KMDCTRACE, fTraceLevel, fTraceName);
- }
-
- if (! mSUCCESS( kstat ) ) {
- printf("Send start trace msg failure, kstat = 0x%08x\n", kstat);
- perror("send");
- exit(1);
- };
-
- }
-
- void SendTraceStop(fTraceName, fTraceLevel, fUseStdOut)
- char *fTraceName;
- int fTraceLevel;
- int fUseStdOut;
- {
- KKStatus kstat;
- if (fUseStdOut) {
- kstat = KMDSend(talkSock, KMDCUNTRACESTDOUT, fTraceLevel, fTraceName);
- } else {
- kstat = KMDSend(talkSock, KMDCUNTRACE, fTraceLevel, fTraceName);
- }
-
- if (! mSUCCESS( kstat ) ) {
- printf("Send stop trace msg failed, kstat = 0x%08x\n", kstat);
- perror("send");
- exit(1);
- };
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int OK;
- char EPName[50];
- static int i, EPLNN, Level;
- KKStatus kstat;
- static char StdTrace[] = "DebugMsg";
- char myHostName[100];
- struct hostent *myHost;
- int machineNameGiven = 0;
- int argCount = argc;
-
- tracename = StdTrace; /* default */
- Level = 3; /* default */
-
- if (argc == 2)
- if (!strcmp(argv[1], "usage")) {
- printf("Usage: trace <options>\n");
- printf(" -T <name>\tStart tracing\n");
- printf(" -S <name>\tStart the trace; output to kernel stdout\n");
- printf(" \t(to stop, use -C in a later call)\n");
- printf(" -l <level>\tSet the trace level for -S & -T\n");
- printf(" \t(must preceed -T and -S)\n");
- printf(" -M <name> \tTrace kernel on the named machine\n");
- printf(" -m <name> \tTrace kernel on the named machine\n");
- printf(" -x [<level>]\tDebugMsg trace\n");
- printf(" -t [<level>]\tMMTrace\n");
- printf("The program waits until it or the kernel dies.\n");
- exit(0);
- }
-
- /*
- * Parse command line options
- */
- while (argc > 1 && argv[1][0] == '-') {
- switch (argv[1][1]) {
- case 'N': /* Set logical node number */
- if (argv[1][2] == '\0') {
- EPLNN = atoi(argv[2]);
- argc--;
- argv++;
- } else
- EPLNN = atoi(&argv[1][2]);
-
- break;
- case 'x':
- case 'n':
- case 'C':
- case 't':
- case 'l':
- case 'T':
- case 'S':
- if (argv[1][2] == '\0') {
- argc--;
- argv++;
- }
- break;
- case 'P': /* Set pid, cancel LNN usage. */
- if (argv[1][2] == '\0') {
- pid = atoi(argv[2]);
- argc--;
- argv++;
- } else
- pid = atoi(&argv[1][2]);
- pidGiven = 1;
- printf("warning: -P ignored.\n");
- break;
- case 'M':
- case 'm':
- if (argv[1][2] == '\0') {
- strcpy(myHostName, argv[2]);
- argc--;
- argv++;
- } else strcpy(myHostName, &argv[1][2]);
- machineNameGiven ++;
- break;
-
- default:
- printf("Warning: Unknown option: %c ignored.\n",
- argv[1][1]);
- break;
-
- }
- argc--;
- argv++;
- }
- argv -= (argCount - argc); /* restore for next pass */
- argc = argCount;
-
- /* Set termination handler. */
- signal(SIGHUP, TerminationHandler);
- signal(SIGQUIT, TerminationHandler);
- signal(SIGINT, TerminationHandler);
- signal(SIGBUS, TerminationHandler);
- signal(SIGSEGV, TerminationHandler);
- signal(SIGTERM, TerminationHandler);
-
- signal(SIGPIPE, PipeHandler);
- signal(SIGALRM, Prodder);
-
- talkSock = socket(AF_INET, SOCK_STREAM, 0, 0);
- if (talkSock < 0) {
- perror("trace: socket");
- exit(1);
- }
-
- if (! machineNameGiven) {
- if (gethostname(myHostName, 100) < 0) {
- perror("trace: gethostname");
- exit(1);
- }
- }
- myHost = gethostbyname(myHostName);
- if (myHost == NULL) {
- perror("trace: gethostbyname");
- exit(1);
- }
-
- bcopy(myHost->h_addr, &destSockDescr.sin_addr, myHost->h_length);
-
- {
- char *emplanename;
- int emPlane = 0;
- int emPort = EMKERNELDEFAULTPORTNUMBER;
- struct servent *myService;
- emplanename = (char *) getenv("EMPLANE");
- if (emplanename != NULL) emPlane = atoi(emplanename);
- #ifdef DIKU
- myService = getservbyname(EMKERNELSERVICEPORT, "tcp");
- if(myService)
- emPort = ntohs(myService->s_port);
- #endif
- destSockDescr.sin_port = htons(emPort + emPlane*4 + 1);
- }
-
- if (connect(talkSock, &destSockDescr, sizeof(destSockDescr)) == -1) {
- perror("trace: connect");
- exit(1);
- }
-
-
- if ( KMDTest )
- printf("Connected to %d\n", ntohs(destSockDescr.sin_port));
-
- if (!mSUCCESS(KMDReceive(talkSock, &MType, &MInt, MString))) {
- printf("Connection reply failed.\n");
- TerminationHandler(0);
- }
- printf("%s", MString);
- /* Start trace/*/
- /*
- * Parse command line options again.
- */
- while (argc > 1 && argv[1][0] == '-') {
- switch (argv[1][1]) {
- case 'N': /* Set logical node number */
- if (argv[1][2] == '\0') {
- argc--;
- argv++;
- };
- break;
- case 'x':
- tracename = "DebugMsg";
- if (argv[1][2] == '\0') {
- Level = atoi(argv[2]);
- argc--;
- argv++;
- } else
- Level = atoi(&argv[1][2]);
- SendTraceStart(tracename, Level, FALSE);
- break;
- case 't':
- if (argv[1][2] == '\0') {
- Level = atoi(argv[2]);
- tracename = "MMTraceMsg";
- argc--;
- argv++;
- } else {
- tracename = "MMTraceMsg";
- Level = atoi(&argv[1][2]);
- }
- SendTraceStart(tracename, Level, FALSE);
- break;
- case 'l':
- if (argv[1][2] == '\0') {
- Level = atoi(argv[2]);
- argc--;
- argv++;
- } else
- Level = atoi(&argv[1][2]);
- break;
- case 'n':
- case 'T':
- if (argv[1][2] == '\0') {
- SendTraceStart(argv[2], Level, FALSE);
- argc--;
- argv++;
- } else SendTraceStart(&argv[1][2], Level, FALSE);
- break;
- case 'S':
- if (argv[1][2] == '\0') {
- SendTraceStart(argv[2], Level, TRUE);
- argc--;
- argv++;
- } else SendTraceStart(&argv[1][2], Level, TRUE);
- break;
- case 'C':
- if (argv[1][2] == '\0') {
- SendTraceStop(argv[2], Level, TRUE);
- argc--;
- argv++;
- } else SendTraceStop(&argv[1][2], Level, TRUE);
- break;
-
- case 'P': /* Set pid, cancel LNN usage. */
- if (argv[1][2] == '\0') {
- argc--;
- argv++;
- }
- break;
- case 'M':
- case 'm':
- if (argv[1][2] == '\0') {
- argc--;
- argv++;
- }
- break;
- default:
- break;
-
- }
- argc--;
- argv++;
- }
- tracing = 1;
-
- fflush(stdout);
- OK = 1;
- while (OK==1) {
- if (!mSUCCESS(KMDReceive(talkSock, &MType, &MInt, MString))) {
- /* Something went wrong, so quit */
- printf("Trace closed\n");
- TerminationHandler(0);
- }
- if ( KMDTest ) {
- printf("Msg from: %d, (%d, %d, %s)\n", talkSock,
- MType, MInt, MString);
- fflush(stdout);
- };
-
- switch ( MType ) {
-
- case KMDCDATA:
- printf("%s", MString);
- fflush(stdout);
- endcase;
-
- case KMDREADLINE:
- {
- char foo[256];
- printf("(edb) ");
- gets(foo);
- KMDSend(talkSock, KMDREADLINEANS, 0, foo);
- }
- endcase;
-
- case KMDCUNTRACE:
- OK = 0; /* quit */
- endcase;
-
- case KMDCERRMSG:
- printf("Error: %s\n", MString);
- fflush(stdout);
- TerminationHandler(0);
- OK = 0; /* quit */
- endcase;
-
- case KMDCLASTMSG:
- printf("%s", MString);
- TerminationHandler(0);
- default:
- printf("**** KMD error: Warning, bad msgtype: %d \n", MType);
- };
- };
- TerminationHandler(0);
- }
-